/*
 * mp_crypt.cpp
 *
 *  Created on: Nov 9, 2014
 *      Author: marc
 */


#include <cstdio>
#include <string.h>
#include <errno.h>

#include "mp_common.hpp"

#ifndef MP_CRYPTLIB_H_
#define MP_CRYPTLIB_H_
#define MP_CRYPTLIB_INTERNAL_DECLARATION
/** \include
 *  Cette application dépend de la version de biblio partagé
 *  libMP_cryptlib.so.x.x.x
 *  Normalement cette biblio devra faire l'objet d'une
 *  installation séparée.
 *  La variable d'environement pour les Shared Libraries
 *  doit être modifée; exemple de commande ;
 *  export LD_LIBRARY_PATH=/home/marc/workspace/MP_cryptlib/Release:$LD_LIBRARY_PATH
 */
#include "mp_crypt.h"
#endif /* MP_CRYPTLIB_H_ */
//#include <alloc.h>

//Vérifie que le compilateur est d'accord avec les supposition qu'on fait
//static_assert(__cplusplus > 199711L, "COMPILE ASSERT FAILED : Program requires C++11 capable compiler");

//char *MPVERSIONMAJOR = "0";
const char *MP_VERSION_MAJOR = "0";
const char *MP_VERSION_MINOR = ".08";
const char *MP_VERSION_REVISION = ".0005";


/** \enum
 *  L'ensemble des erreurs que cette librairie peut remonter
 */
enum mp_crypt_error {
	MP_CRYPTERR_NO_ERR = -8890,                    //!< MP_CRYPTERR_NO_ERR
	MP_CRYPTERR_EMPTY_PUBLIC_STRING = -8892,   //!< MP_CRYPTERR_EMPTY_PUBLIC_STRING
	MP_CRYPTERR_TOO_LONG_PUBLIC_STRING = -8893,//!< MP_CRYPTERR_TOO_LONG_PUBLIC_STRING
	MP_CRYPTERR_LIBRARY_DEPENDANCY_FAIL = -8894//!< MP_CRYPTERR_LIBRARY_DEPENDANCY_FAIL
} e;


/**
 * La variable globale qui contient le code erreur
 */
mp_crypt_error mp_errno = MP_CRYPTERR_NO_ERR;

/**
 * La variable d'enum intermédiare qui contient le type de cryptage à attribuer
 */
mp_crypt_h::crypt_type_struct mp_crypttype = {0,1,2,3,4,5};

struct mp_crypt_sequence {
	int step1;
	int step2;
	int step3;
} global_crypt_sequence = {
	mp_crypttype.MP_CRYPTTYPE_UNKNOWN,
	mp_crypttype.MP_CRYPTTYPE_UNKNOWN,
	mp_crypttype.MP_CRYPTTYPE_UNKNOWN
};


/**
 * applique le cryptage spécial maison
 * @param [in,out] P  la référence au pointeur qui contient la chaine
 * @return enum mp_crypt_error
 */
signed int mp_getEncrypt(char *P) {
	signed int retval = 0;
	char *k = "Bollocs                       ";
	if (strlen(P) == 0) {
		if (errno) {
			retval = errno;
		}
		else  {
			retval = mp_errno = MP_CRYPTERR_EMPTY_PUBLIC_STRING;
		}

	}
	else {
		if (strlen(P) >= 256) {
			if (errno) {
				retval = errno;
			}
			else  {

				retval = mp_errno = MP_CRYPTERR_TOO_LONG_PUBLIC_STRING;
			}

		}
		else {
			int o = strlen(P);
			char *rev = (char *)calloc(o+1,sizeof(char));
			//strcpy(rev," Plouc !                                 ");

			strcpy(rev,(const char *)P);

			for (int i = 0;  i < o; i++ ) {
				//strcpy((char *)k[4 + i],(const char *)rev[o - i]);
				P[i] = rev[(o - 1) - i];
/*				P[1] = rev[5];
				P[5] = rev[1];
				P[0] = 'Z';
				P[2] = rev[3];
				P[4] = 'T';*/
			}
			P[o] = 0;
			//strcpy(P,(const char *)rev);
			free(rev);
			retval = mp_errno = MP_CRYPTERR_NO_ERR;

		}
	}
	return retval;
}
/**
 * Renvoi deux versions du numéro de version de cette bibliothèque C pour Linux
 * @param J pointeur vers un ensemble de pointeurs vers char
 * @return int toujours 1
 */int mp_getVersion(char **J) {
	 char k[2][256];
	 int indxr = 0;
	 int offs = 0;

	// k[0][0 + 3] = '7';
	 //strcpy(k[0] + 4,"99");
	 offs = 0;
	 strcpy(k[0] + offs,MP_VERSION_MAJOR);
	 offs = offs + strlen(MP_VERSION_MAJOR) ;
	 strcpy(k[0] + offs ,MP_VERSION_MINOR);
	 strcat(k[0],MP_VERSION_REVISION);
	/*void *tm;
	void *ty;
	char *oyy;
	tm = calloc(2,sizeof(char));
	ty = calloc(256,sizeof(char));*/
//	strcpy(k[0],(char *)strncat((char *)"Version",MP_VERSION_FULL_STR,255));
	//strcpy(k[0],(char *)strncat("Version"," 0.000",256));
	 indxr = 0;
	 // TODO refactor this series of repeating function calls
	 char zf[4][256];
	 strcat(J[indxr],"Version ");
	 strcat(J[indxr],MP_VERSION_MAJOR);
	 strcat(J[indxr],MP_VERSION_MAJOR);
	 strcat(J[indxr],MP_VERSION_REVISION);
	 indxr = indxr + 1;
//	strcpy(J[0 + (inn * sizeof(char))],"0.06 R5899");
	strcpy(J[0 + (indxr * sizeof(char))],k[0]);
	/*strcpy(oyy,"0.05");
	memcpy(d *)ty,(void *)oyy,256);
	tm = ty;*/
	mp_errno = MP_CRYPTERR_NO_ERR;
	return mp_errno;
}

 // TODO  déplacer cette fontion dans l'util quand on aura dépanné
 int mp_isMemberIntStructure(int findThisInt, int *inStructHavingOnlyInt_Ptr, int sizeStruct) {

	 int Structwidth = sizeStruct /sizeof(int);
	 for (int i = 0; i< Structwidth; i++)
	 {
		 if (findThisInt == inStructHavingOnlyInt_Ptr[i]) {
			 return 1;
		 }
	 }
	 return 0;
 }
 int mp_setEncryptType(int new_crypt_type){

/*	 switch ()
	 *mp_current_encryption = new_crypt_type ;*/
		/**
		 * La variable globale qui contient le type de cryptage en cours
		 */
	 int suu  =0;


	 if (mp_isMemberIntStructure(new_crypt_type, &mp_crypt_h::mp_crypt_types.MP_CRYPTTYPE_UNKNOWN, sizeof(mp_crypt_h::mp_crypt_types))) {
		 global_crypt_sequence.step1 = new_crypt_type;
		 int* kjj = &mp_crypt_h::mp_crypt_types.MP_CRYPTTYPE_UNKNOWN;
		 int struss = sizeof(mp_crypt_h::mp_crypt_types) /sizeof(int);
		 for (int i = 0; i< struss; i++)
		 {
			 suu = suu + kjj[i];
		 }

	 }
	 else {
		 global_crypt_sequence.step1 = new_crypt_type;
		 suu = 999999;
	 }

int mp_current_encryption;
//mp_current_encryption  = (int)mp_crypttype.MP_CRYPTTYPE_NONE;
mp_current_encryption  = mp_crypt_h::mp_crypt_types.MP_CRYPTTYPE_REVERSE;

mp_current_encryption = suu;

return mp_current_encryption;
 }


